"""
-------------------------------------------------
   File Name：     CrackVerifyCode.py
   Description :   处理验证码
   Author :        Cyrus_Ren
   date：          2018/12/8
-------------------------------------------------
   Change Activity:
                   
-------------------------------------------------
"""
__author__ = 'Cyrus_Ren'

from PIL import Image
import requests
import base64
import re
import time
from GetConfig import config
from urllib.parse import quote_plus, urlencode
from GetConfig import config

HEADER = config.crawl_headers


class CrackCode(object):
    def get_image(self, current_url, session, page_source):
        '''
        获取验证码图片
        '''
        self.header = HEADER
        self.session = session
        # 获得验证码图片地址
        imgurl_pattern_compile = re.compile(r'.*?<img src="(.*?)".*?')
        img_url = re.search(imgurl_pattern_compile, page_source).group(1)
        try:
            self.current_url = re.search(r'(.*?)#', current_url).group(1)
        except Exception as e:
            self.current_url = current_url
        self.re_current_url = re.search(r'.net(.*)', self.current_url).group(1)
        # 下载图片
        img_url = 'http://kns.cnki.net' + img_url
        image_res = self.session.get(img_url, headers=self.header)
        with open('data/crack_code.jpeg', 'wb') as file:
            file.write(image_res.content)
        image_trans = Image.open('data/crack_code.jpeg')
        # 转化为png
        for i, frame in enumerate(iter_frames(image_trans)):
            frame.save('data/crack_code.png', **frame.info)
        # 是否自动识别
        if config.crawl_iscrackcode == 1:
            return self.crack_code()
        else:
            return self.handle_code()

    def crack_code(self):
        '''
        自动识别验证码
        '''
        baiduTool = BaiduYun()
        result = baiduTool.get_verify_code()
        print("验证码:", result)
        self.send_code(result)

    def handle_code(self):
        '''
        手动识别验证码
        '''
        image = Image.open('crack_code.jpeg')
        image.show()
        code = input('出现验证码，请手动输入：')
        return self.send_code(code)

    def send_code(self, code):
        '''
        发送验证码
        '''
        # 对发送链接进行处理
        re_url = quote_plus(self.re_current_url)
        re_url = re.sub(r'%2F', '%2f', re_url)
        re_url = re.sub(r'%3F', '%3f', re_url)
        re_url = re.sub(r'%3D', '%3d', re_url)
        send_url = 'http://kns.cnki.net/kns/brief/vericode.aspx?rurl=' + re_url + '&vericode=' + code
        self.header['Referer'] = send_url
        self.header['Upgrade-Insecure-Requests'] = '1'
        return self.session.get(send_url, headers=self.header).text


class BaiduYun(object):

    # 百度云AI接口

    def __init__(self):
        api_key = ''
        secret_key = ''
        self.access_token = self.get_access_token(api_key, secret_key)

    def get_access_token(self, api_key, secret_key):
        # 获取access_token
        res = requests.get(
            f"https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id={api_key}&client_secret={secret_key}")
        if res.status_code == 200:
            access_token = res.json()['access_token']
            return access_token
        else:
            return ''

    def get_verify_code(self):
        # 文字识别
        access_token = self.access_token
        request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic"
        # 二进制方式打开图片文件
        f = open('data/crack_code.png', 'rb')
        img = base64.b64encode(f.read())
        params = {"image": img}
        request_url = request_url + "?access_token=" + access_token
        headers = {'content-type': 'application/x-www-form-urlencoded'}
        response = requests.post(request_url, data=params, headers=headers)
        if response:
            result = response.json()
            return result.get('words_result', [{}])[0].get('words', '')
        return ''


#将gif图片转成PNG图片
# def to_png():
#     im = Image.open('data/crack_code.jpeg')
#     for i, frame in enumerate(iter_frames(im)):
#         frame.save('data/crack_code.png', **frame.info)


# 将gif图片转成PNG图片
def iter_frames(im):
    try:
        i = 0
        while 1:
            im.seek(i)
            imframe = im.copy()
            if i == 0:
                palette = imframe.getpalette()
            else:
                imframe.putpalette(palette)
            yield imframe
            i += 1
    except EOFError:
        pass


crack = CrackCode()

if __name__ == "__main__":
    # to_png()
    pass
